package sg.edu.nus.iss.umpire.dao.jpa;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import sg.edu.nus.iss.umpire.dao.UmpireDao;
import sg.edu.nus.iss.umpire.domain.Umpire;

import com.google.appengine.api.memcache.Expiration;
import com.google.appengine.api.memcache.MemcacheService;
import com.google.appengine.api.memcache.MemcacheServiceFactory;

public class UmpireDAOImpl extends BaseDaoImpl<Long, Umpire> implements UmpireDao {

	public UmpireDAOImpl(EntityManager em) {
		super(em);
	}

	@Override
	public Umpire findUmpireByNRIC(String nric) {
			String query = "SELECT FROM " + Umpire.class.getName()
					+ " umpire where nric=:nric";
			Query q = em.createQuery(query).setParameter("nric", nric);
			q.setHint("datanucleus.appengine.datastoreReadConsistency",
					"EVENTUAL");
			List<Umpire> umpires = (List<Umpire>) q.getResultList();
			return null != umpires && 0 != umpires.size() ? umpires.get(0)
					: null;
	}

	@Override
	public Umpire findUmpireByEmail(String email) {
			String query = "SELECT FROM " + Umpire.class.getName()
					+ " umpire where email=:email";
			Query q = em.createQuery(query).setParameter("email", email);
			q.setHint("datanucleus.appengine.datastoreReadConsistency",
					"EVENTUAL");
			List<Umpire> umpires = (List<Umpire>) q.getResultList();
			return null != umpires && 0 != umpires.size() ? umpires.get(0)
					: null;
	}


	@Override
	public List<Umpire> findUmpireByLocation(String address) {

			String query = "SELECT FROM " + Umpire.class.getName()
					+ " umpire where umpire.address =:address";
			Query q = em.createQuery(query).setParameter("address", address);

			q.setHint("datanucleus.appengine.datastoreReadConsistency",
					"EVENTUAL");
			List<Umpire> umpires = (List<Umpire>) q.getResultList();
			return umpires;
	}

	@Override
	public List<Umpire> findUmpireByType(String umpireType) {
			String query = "SELECT FROM " + Umpire.class.getName()
					+ " umpire where umpire.umpireType=:umpireType";
			Query q = em.createQuery(query).setParameter("umpireType",
					umpireType);

			q.setHint("datanucleus.appengine.datastoreReadConsistency",
					"EVENTUAL");
			List<Umpire> umpires = (List<Umpire>) q.getResultList();
			return umpires;
	}

	@Override
	public List<Umpire> findUmpireByIds(List<Long> ids) {
		List<Umpire> umpires = new ArrayList<Umpire>();
		for (Long id : ids) {
			umpires.add(getByKey(id));
		}
		
		return umpires;
	}
	
	@Override
	public List<Umpire> getAllUmpires() {
		List<Umpire> umpires = null;

		MemcacheService memcache = MemcacheServiceFactory.getMemcacheService();
		// Check if item is in cache
		boolean umpireListAreCached = memcache.contains("umpireList");

		if (!umpireListAreCached) {

			String query = "SELECT FROM " + Umpire.class.getName() + " umpire";
			Query q = em.createQuery(query);
			q.setHint("datanucleus.appengine.datastoreReadConsistency",
					"EVENTUAL");
			umpires = (List<Umpire>) q.getResultList();

			memcache.put("umpireList",
					umpires.toArray(new Umpire[umpires.size()]),
					Expiration.byDeltaSeconds(60));
		} else {
			// retrieve list from cache
			Umpire[] arrUmpires = (Umpire[]) memcache.get("umpireList");
			umpires = Arrays.asList(arrUmpires);

		}
		return umpires;
	}

}
